// Package queue queue/bounded_queue.go
package queue

import (
	"sync"
)

// BoundedQueue 一个基于通道的有界队列实现
type BoundedQueue struct {
	queue    chan interface{}
	mu       sync.Mutex
	closed   bool
	capacity int
}

// NewBoundedQueue 创建一个新的有界队列
func NewBoundedQueue(capacity int) *BoundedQueue {
	return &BoundedQueue{
		queue:    make(chan interface{}, capacity),
		closed:   false,
		capacity: capacity,
	}
}

// Put 将任务放入队列 (可能阻塞)
func (q *BoundedQueue) Put(task interface{}) error {
	q.mu.Lock()
	if q.closed {
		q.mu.Unlock()
		return ErrQueueClosed
	}
	q.mu.Unlock()

	// 非阻塞地尝试将任务放入队列
	select {
	case q.queue <- task:
		return nil
	default:
		// 如果队列已满，则阻塞地放入任务
		q.queue <- task
		return nil
	}
}

// Get 从队列获取任务 (阻塞)
func (q *BoundedQueue) Get() (interface{}, error) {
	q.mu.Lock()
	if q.closed && len(q.queue) == 0 {
		q.mu.Unlock()
		return nil, ErrQueueClosed
	}
	q.mu.Unlock()

	// 阻塞地获取任务
	task, ok := <-q.queue
	if !ok {
		return nil, ErrQueueClosed
	}
	return task, nil
}

// Close 关闭队列，不再接受新任务
func (q *BoundedQueue) Close() error {
	q.mu.Lock()
	defer q.mu.Unlock()

	if q.closed {
		return nil
	}

	q.closed = true
	close(q.queue)
	return nil
}

// Clear 清理队列中的所有数据（用于本次运行结束后）
func (q *BoundedQueue) Clear() error {
	q.mu.Lock()
	defer q.mu.Unlock()

	// 如果队列已关闭，则不做任何操作
	if q.closed {
		return nil
	}

	// 清空队列中的所有数据
	for {
		select {
		case <-q.queue:
			// 持续取出队列中的数据，直到队列为空
		default:
			// 队列为空，退出循环
			return nil
		}
	}
}

// IsClosed 检查队列是否已关闭
func (q *BoundedQueue) IsClosed() bool {
	q.mu.Lock()
	defer q.mu.Unlock()
	return q.closed
}
